package persistencia;

import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import bean.InputOutputFault;
import bean.PEWSOperation;
import bean.PEWSOperations;
import bean.PortType;
import bean.WSDLOperation;

/*
 * Classe que extrai dados do xpews e wsdl e coloca nos seus respctivos objetos
 */

public class Parse {
	Extrator extrator;
	
	public Extrator getExtrator() {
		return extrator;
	}

	public void setExtrator(Extrator extrator) {
		this.extrator = extrator;
	}
	
	public Parse(String arquivo) throws ParserConfigurationException, SAXException, IOException{
		extrator = new Extrator(arquivo);
	}
	
	// Retorna um objeto "PEWSOperations"
	public PEWSOperations getPEWSOperations(){
		Node pewsNode = extrator.buscarTagPorNome("operations");
		return xpewsParsePEWSOperations(pewsNode);
	}
	
	// Retorna um objeto "PEWSOperations"
	private PEWSOperations xpewsParsePEWSOperations(Node noLocal){
		PEWSOperations pewsOps = new PEWSOperations(xpewsParsePEWSOperation(noLocal.getChildNodes()));
		return pewsOps;
	}
	
	// Retorna um um ArrayList de PEWSOperation,
	// onde cada item do array list é um nó "operation" no arquivo XPEWS.
	private ArrayList<PEWSOperation> xpewsParsePEWSOperation(NodeList lista){
		ArrayList<PEWSOperation> pewsOps = new ArrayList<PEWSOperation>();
		
		for(int i = 0; i < lista.getLength(); i++){
			if(lista.item(i).getNodeType() == Node.ELEMENT_NODE){
				PEWSOperation pews = new PEWSOperation();
				pews.setName(lista.item(i).getAttributes().item(0).getNodeValue());
				pews.setNs(lista.item(i).getAttributes().item(2).getNodeValue());
				pewsOps.add(pews);
			}
		}
		
		return pewsOps;
	}
	
	// Retorna um objeto "PortType"
	public PortType getPortType(){
		Node portTypeNode = extrator.buscarTagPorNome("wsdl:portType");
		
		return wsdlParsePortType(portTypeNode);
	}
	
	// Retorna um objeto "PortType"
	private PortType wsdlParsePortType(Node noLocal){
		PortType portType = new PortType();
				
		portType.setNome(noLocal.getAttributes().item(0).getNodeValue());
		portType.setOperation(wsdlParseWSDLOperations(noLocal.getChildNodes()));
		
		return portType;
	}
	
	// Retorna um objeto ArrayList de Operations,
	// onde cada item do array list é um nó "wsdl:operation"
	private ArrayList<WSDLOperation> wsdlParseWSDLOperations(NodeList lista){
		ArrayList<WSDLOperation> operations = new ArrayList<WSDLOperation>();
		
		for(int i = 0; i < lista.getLength(); i++){
			if(lista.item(i).getNodeType() == Node.ELEMENT_NODE){
				WSDLOperation operation = new WSDLOperation();
				operation.setName(lista.item(i).getAttributes().item(0).getNodeValue());
				operation.setInput(wsdlParseinputOutputFault(lista.item(i).getChildNodes(), 1));
				operation.setOutput(wsdlParseinputOutputFault(lista.item(i).getChildNodes(), 3));
				operations.add(operation);
			}
		}
		return operations;
	}
	
	// Retorna um objeto "InputOutputFault" podendo este ser um dos 3 (input, output, fault)
	private InputOutputFault wsdlParseinputOutputFault(NodeList lista, int i){
		InputOutputFault iOF = new InputOutputFault();
		
		if(lista.item(i).getNodeType() == Node.ELEMENT_NODE && lista.item(i).hasAttributes()){
			iOF.setMessage(lista.item(i).getAttributes().item(0).getNodeValue());
			iOF.setName(lista.item(i).getAttributes().item(1).getNodeValue());
		}
		
		return iOF;
	}
}	
